package com.xbongbong.paas.toolbox.util;

import com.xbongbong.paas.enums.DateEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.enums.errorcodes.BusinessRuleErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;

/**
 * @author: wufeng
 * @date: 2018/11/30 16:06
 * @desrcption:
 */
public class PaasDateUtil {

    private static final Integer MONTH = 12;

    public static SimpleDateFormat SDFDate = new SimpleDateFormat("yyyy-MM-dd");

    public static SimpleDateFormat SDF = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    public static SimpleDateFormat SDFYMDHM = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm");

    /**
     * 计算时间 得出一个长度为2的列表
     * @param commitTime
     * @return
     * @throws XbbException
     */
    public static List<Object> computeTime(List<Object> commitTime) throws XbbException {
        List<Object> resultList = new ArrayList();
        String dateType = (String)commitTime.get(0);
        DateEnum dateEnum = DateEnum.getDateEnum(dateType);
        switch (dateEnum) {
            case TODAY:
                resultList.add(GetTimeInMillisUtil.getTimesMorning());
                resultList.add( GetTimeInMillisUtil.getTimesNight());
                break;
            case YESTERDAY:
                resultList.add( GetTimeInMillisUtil.getBeginDayOfYesterday().getTime()/1000);
                resultList.add( GetTimeInMillisUtil.getEndDayOfYesterday().getTime()/1000);
                break;
            case THIS_WEEK:
                resultList.add(GetTimeInMillisUtil.getTimesWeekMorning());
                resultList.add(GetTimeInMillisUtil.getTimesWeekNight());
                break;
            case LAST_WEEK:
                resultList.add(GetTimeInMillisUtil.getBeginDayOfLastWeek().getTime()/1000);
                resultList.add( GetTimeInMillisUtil.getEndDayOfLastWeek().getTime()/1000);
                break;
            case THIS_MONTH:
                resultList.add( GetTimeInMillisUtil.getTimesMonthMorning());
                resultList.add( GetTimeInMillisUtil.getTimesMonthNight());
                break;
            case LAST_MONTH:
                resultList.add(GetTimeInMillisUtil.getBeginDayOfLastMonth().getTime()/1000);
                resultList.add(GetTimeInMillisUtil.getEndDayOfLastMonth().getTime()/1000);
                break;
            case TOMORROW:
                resultList.add(GetTimeInMillisUtil.getTomorrowBegin());
                resultList.add(GetTimeInMillisUtil.getTomorrowEnd());
                break;
            case NEXT_WEEK:
                resultList.add(GetTimeInMillisUtil.getNextWeekBegin());
                resultList.add(GetTimeInMillisUtil.getNextWeekEnd());
                break;
            case NEXT_MONTH:
                resultList.add(GetTimeInMillisUtil.getNextMonthBegin());
                resultList.add(GetTimeInMillisUtil.getNextMonthEnd());
                break;
            case THIS_QUARTER:
                resultList.add(GetTimeInMillisUtil.getThisQuarterBegin());
                resultList.add(GetTimeInMillisUtil.getThisQuarterEnd());
                break;
            case LAST_QUARTER:
                resultList.add(GetTimeInMillisUtil.getLastQuarterBegin());
                resultList.add(GetTimeInMillisUtil.getLastQuarterEnd());
                break;
            case NEXT_QUARTER:
                resultList.add(GetTimeInMillisUtil.getNextQuarterBegin());
                resultList.add(GetTimeInMillisUtil.getNextQuarterEnd());
                break;
            case FIRST_HALF_YEAR:
                resultList.add(GetTimeInMillisUtil.getFirstHalfYearBegin());
                resultList.add(GetTimeInMillisUtil.getFirstHalfYearEnd());
                break;
            case SECOND_HALF_YEAR:
                resultList.add(GetTimeInMillisUtil.getSecondHalfYearBegin());
                resultList.add(GetTimeInMillisUtil.getSecondHalfYearEnd());
                break;
            case THIS_YEAR:
                resultList.add(GetTimeInMillisUtil.getThisYearBegin());
                resultList.add(GetTimeInMillisUtil.getThisYearEnd());
                break;
            case LAST_YEAR:
                resultList.add(GetTimeInMillisUtil.getLastYearBegin());
                resultList.add(GetTimeInMillisUtil.getLastYearEnd());
                break;
            case NEXT_YEAR:
                resultList.add(GetTimeInMillisUtil.getNextYearBegin());
                resultList.add(GetTimeInMillisUtil.getNextYearEnd());
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        return resultList;
    }

    /**
     * 将日期转到00:00:00
     * @param dateInt
     * @return
     */
    public static Long getBeforeDayBreak(Long dateInt) {
        if (Objects.isNull(dateInt) || Objects.equals(0L, dateInt)) {
            return null;
        }
        String dateString = DateTimeUtil.getDateStringEpochSecond(dateInt);
        String beforeDateString = dateString + " 00:00:00";
        Long beforeDate = DateTimeUtil.getInt(beforeDateString, DateTimeUtil.SDF);
        if (Objects.equals(0L, beforeDate)) {
            return null;
        }
        return beforeDate;
    }

    /**
     * 将日期转到23:59:59
     * @param dateInt
     * @return
     */
    public static Long getDayLastSecond(Long dateInt) {
        if (Objects.isNull(dateInt) || Objects.equals(0L, dateInt)) {
            return null;
        }
        String dateString = DateTimeUtil.getDateStringEpochSecond(dateInt);
        String beforeDateString = dateString + " 23:59:59";
        Long beforeDate = DateTimeUtil.getInt(beforeDateString, DateTimeUtil.SDF);
        if (Objects.equals(0L, beforeDate)) {
            return null;
        }
        return beforeDate;
    }

    /**
     * 将日期转到00秒
     * @param dateInt
     * @return
     */
    public static Long getDateFirstSecond(Long dateInt) {
        String dateString = DateTimeUtil.getStringEpochSecond(dateInt, DateTimeUtil.SDFYMDHM);
        String beforeDateString = dateString + ":00";
        Long beforeDate = DateTimeUtil.getInt(beforeDateString, DateTimeUtil.SDF);
        if (Objects.equals(0L, beforeDate)) {
            return null;
        }
        return beforeDate;
    }




    /**
     * 将日期转到59秒
     * @param dateInt
     * @return
     */
    public static Long getDateLastSecond(Long dateInt) {
        String dateString = DateTimeUtil.getStringEpochSecond(dateInt, DateTimeUtil.SDFYMDHM);
        String beforeDateString = dateString + ":59";
        Long beforeDate = DateTimeUtil.getInt(beforeDateString, DateTimeUtil.SDF);
        if (Objects.equals(0L, beforeDate)) {
            return null;
        }
        return beforeDate;
    }

    public static void main(String[] args) {
        System.out.println(getDateFirstSecond(1577776940L));
        System.out.println(getDateLastSecond(1577776940L));
    }

    public static SimpleDateFormat getDate(String value) {
        if(RegexUtil.isDateSDF(value)) {
            // \d{4}-\d{2}-\d{2}
            return SDFDate;
        }else if (RegexUtil.isTime(value)) {
            // \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
            return SDF;
        } else if (RegexUtil.isTimeNoSecond(value)) {
            return SDFYMDHM;
        }
        return null;
    }

    public static Long getInt(Object value) throws XbbException {
        if (Objects.isNull(value)) {
            return null;
        }
        // 是时间戳
        Boolean isTimestamp = value instanceof Long || value instanceof Integer;
        // 是yyyy-MM-dd 或者 yyyy-MM-dd HH:mm 或者 yyyy-MM-dd HH:mm:SS
        Boolean isDate = RegexUtil.isDate(value.toString());
        if (!isDate && !isTimestamp) {
            throw new XbbException(BusinessRuleErrorCodeEnum.API_ERROR_261007);
        }
        if (isDate) {
            String date = String.valueOf(value);
            SimpleDateFormat simpleDateFormat = getDate(date);
            return DateTimeUtil.getInt(date, simpleDateFormat);
        } else {
            return Long.valueOf(String.valueOf(value));
        }
    }


    public static Integer getWeekNum(Long date, Integer value) {
        int month = DateTimeUtil.getMonth4Someday(date);
        int weekNum = DateTimeUtil.getWeekOfYear(date,value);
        if (month == MONTH && weekNum == 1) {
            // 如果是12月份，并且是第二年的第一周，需要取最大值
            weekNum =  DateTimeUtil.getWeekOfYearMax(date, Calendar.SUNDAY);
        }
        return weekNum;
    }
}
